
<template>
  <div class="map-container" :="getMapOptions" />
  <div class="indexSelector">
    <n-select v-model:value="currentAirIndex" :options="selectOption" size="small" />
  </div>
  <div class="legend">
    <div style="position: fixed;left: 0;top: 0;z-index: 9999;background-color: #fff;width: 500px;height: 500px;" />
    <colorInterval />
  </div>
</template>

<script>

import { reactive, toRefs, onMounted, computed, watch, onBeforeUnmount, nextTick, watchEffect, createVNode, render } from 'vue'

import { Map, View, Feature, Overlay } from 'ol'
import 'ol/ol.css'
import { Tile, Vector as VectorLayer } from 'ol/layer'
// import TileWMS from 'ol/source/TileWMS.js'
import LineString from 'ol/geom/LineString'
import Point from 'ol/geom/Point'
import { Style, Text, Fill } from 'ol/style'
import { XYZ, Vector as VectorSource } from 'ol/source'
import { transform, fromLonLat } from 'ol/proj'
import { getVectorContext } from 'ol/render'
import VectorContext from 'ol/render/VectorContext'
import * as control from 'ol/control'
import GeoJSON from 'ol/format/GeoJSON.js'
import * as turf from '@turf/turf'

import { styleList } from '@/utils/style.js'
// import { airportList } from '@/api/dashboard/index.js'
import gcj02Mecator from '@/utils/map/gcj02Mecator.js'
import { geomStyles } from '@/utils/map/geomStyle.js'
import { getColorByValue } from '@/utils/map/AQIColorStyle.js'

import { routeByTask } from '@/api/dashboard/index.js'
import { getAirDataType, getAirtData } from '@/api/air-data/index.js'
import { getFlightData } from '@/api/flight-data/index.js'
import OSS from 'ali-oss'
import { getOssAuth } from '@/api/common/upload.js'
import { exportReport } from '@/api/air-data/index.js'
// import { Polygon } from 'ol/geom'
// import { feature } from '@turf/turf'
// import object from 'element-resize-detector/src/detection-strategy/object'

import squareWindow from './suqareInfo.vue'
import colorInterval from './colorInterval.vue'
export default {
  name: 'UnderLay',
  components: colorInterval,
  props: {
    id: {
      type: String,
      default: 'underlay'
    },
    selectedInfo: {
      type: Object,
      default: () => { }
    },
    videoInfo: {
      type: Object,
      default: () => { }
    }
  },
  emits: ['distance'],
  setup(props, { emit }) {
    const data = reactive({
      map: null,
      view: null,
      drawerShow: false,
      trackLayer: null,
      trackInfo: null,
      // 轨迹数据
      trackList: [],
      socket: null,
      liveTrackLayer: null,
      trackTimer: null,
      airLayer: null,
      // 所有矢量图层
      vectorLayers: [],
      squareLayer: null, // 方格图层
      cellSide: 200, // 方格的边长，单位为米
      warningLngLat: [],
      squareFeatures: [], // 所有的方格feature数组
      airIndexList: [], // 所有的空气指标
      selectOption: [], // 空气指标下拉框选项
      currentAirIndex: 'pm_2_5', // 当前所选空气指标
      airLine: [],
      featureArr: [], // 最终用于绘制的网格数组
      monitorInfo: {},
      airData: null, // 所有的大气监测的点数据（包含属性数据）
      legendSrc: '',
      mountNode: null, // 弹窗挂载的dom结构
      airInfoOverlay: null, // 弹窗的地图overlay
      gridCenter: null // 所有网格的中心点坐标
    })

    const taskId = computed(() => props.selectedInfo.currentTask)
    const airport = computed(() => props.selectedInfo.currentAirport[0])
    const type = computed(() => props.selectedInfo.type)

    watchEffect(() => {
      const current = data.airIndexList.filter(e => e.dataType === data.currentAirIndex)
      data.legendSrc = current[0]?.referenceIndicatorVerticalImage
    })

    // 修改当前关注的
    watch(() => data.currentAirIndex, newV => {
      if (!data.airData) return
      airInfowindowClose()
      data.featureArr.forEach(e => {
        e.setProperties({
          propsArr: [],
          value: null,
          valueArr: []
        })
      })
      data.airData.forEach(e => {
        squareFilter(e)
      })
    }, { deep: true })

    // 回放时，视频与地图的联动
    watch(() => props.videoInfo, newV => {
      nextTick(() => {
        if (!data.map) {
          // getTrackData(taskId.value).then(({ trackList }) => {
          //   data.trackInfo = initTrack(formatTradeList(trackList), 'liveTrackLayer', 'route')
          // })
          data.trackInfo = initTrack(formatTradeList(data.trackList), 'liveTrackLayer', 'route')
        }
      })
    }, { deep: true, immediate: true })
    // 获取航线
    function getAirLine() {
      routeByTask(taskId.value).then(res => {
        if (res.code !== 0) return
        data.airLine = res.data.data
        // 构建网格
        createSquareGrid()
      })
    }
    getAirLine()

    // 构建航线外接矩形,并划分网格
    function createSquareGrid() {
      if (!data.airLine) return
      let minX = data.airLine[0].lon
      let minY = data.airLine[0].lat
      let maxX = 0
      let maxY = 0
      const handledLine = []
      const cellSide = data.cellSide
      const degree = turf.lengthToDegrees(cellSide / 5, 'meters')
      // 根据航线的最大最小经纬度构建外接多边形
      data.airLine.forEach(e => {
        minX = (e.lon > minX ? minX : e.lon) * 1 - degree
        minY = (e.lat > minY ? minY : e.lat) * 1 - degree
        maxX = (e.lon < maxX ? maxX : e.lon) * 1 + degree
        maxY = (e.lat < maxY ? maxY : e.lat) * 1 + degree
        e = [e.lon, e.lat]
        handledLine.push(e)
      })
      data.gridCenter = (minX + maxX) / 2 + 'E,' + (minY + maxY) / 2 + 'N'
      // 根据外接多边形画出网格
      const boundingBox = [minX, minY, maxX, maxY]

      const options = { units: 'meters' }
      const squareGrid = turf.squareGrid(boundingBox, cellSide, options)
      squareGrid.features.forEach((square, index) => {
        square.valueArr = []
      })
      data.squareFeatures = squareGrid.features
      // 画出网格线加载到map中，需要先坐标转换
      const format = new GeoJSON()
      const olFeature = format.readFeatures(squareGrid)// 得到结果geojson中的feature数据
      olFeature.forEach((e, index) => {
        const geom = e.getGeometry().transform('EPSG:4326', 'EPSG:3857')
        e.setGeometry(geom)
        e.setId(index)
        e.setProperties({
          id: index,
          valueArr: [],
          value: null,
          propsArr: [],
          lonArr: [],
          latArr: []
        })
      })
      drawFeature(olFeature)

      // squareFilter()
    }

    // 通过无人机传回的点位来筛选具体哪些方框需要显示
    function squareFilter(point) {
      // const featureArr = data.featureArr
      const pt = turf.point([point.longitude * 1, point.latitude * 1])
      data.squareFeatures.forEach((e, index) => {
        // 判断点有没有落在feature中
        const isIn = turf.booleanPointInPolygon(pt, e)
        if (isIn) {
          // 若点在feature中，首先获取该feature，并将该点的测值存储到feature的属性数组中
          const feature = data.featureSource.getFeatureById(index)
          // 将属性数据存储到feature的数组中
          const propsArr = feature.get('propsArr')
          propsArr.push(point)
          // 计算当前关注的测值
          const valueArr = feature.get('valueArr')

          let i
          if (data.currentAirIndex === 'pm_2_5') {
            i = 'pm25'
          } else if (data.currentAirIndex === 'pm_10') {
            i = 'pm10'
          } else {
            i = data.currentAirIndex
          }

          valueArr.push(point[i] * 1)

          const featureValue = feature.get('value')
          const average = getAverage(valueArr)
          if (featureValue === average) return

          const lonArr = feature.get('lonArr')
          const latArr = feature.get('latArr')
          lonArr.push(point.longitude * 1)
          latArr.push(point.latitude * 1)

          feature.setProperties({
            value: average,
            longitude: getAverage(lonArr),
            latitude: getAverage(latArr)
          })
          feature.setStyle(function(item) {
            const text = item.get('value').toFixed(2)
            const color = getColorByValue(average, data.currentAirIndex)
            return new Style({
              fill: new Fill({
                color: color
              }),
              text: new Text({
                // 文字内容
                text: text,
                // 位置
                textAlign: 'center',
                // 基准线
                textBaseline: 'top',
                offsetY: 0,
                // 文字样式
                font: 'normal 12px SourceHanSansCN-Medium',
                // backgroundFill: new Fill({
                //   color: '#1890FF'
                // }),
                // padding: [3, 6, 3, 6],
                // 文字颜色
                fill: new Fill({
                  color: 'rgba(0, 0, 0, 1)'
                })
              })
            })
          })
          // 将涉及的方块feature存储起来
          if (data.featureArr.indexOf(feature) === -1) {
            data.featureArr.push(feature)
          }
        }
      })
    }

    // 因为对于地图渲染的压力过大，暂时弃用该方法
    // // 筛选出与测点有交集的网格 直播情况与回放会有所不同
    // function squareFilter(point) {
    //   const featureArr = data.featureArr
    //   // 先写死一个点位，后续该点位应取无人机传回的点位
    //   // const pt = turf.point([118.75906729285002, 31.825836584108633])
    //   const pt = turf.point([point.longitude * 1, point.latitude * 1])
    //   data.squareFeatures.forEach((e, index) => {
    //     // 判断点有没有落在feature中
    //     const isIn = turf.booleanPointInPolygon(pt, e)
    //     if (isIn) {
    //       const format = new GeoJSON()
    //       const olFeature = format.readFeature(e)
    //       const geom = olFeature.getGeometry().transform('EPSG:4326', 'EPSG:3857')
    //       olFeature.setGeometry(geom)

    //       // 获取点携带的检测值并计算

    //       //     // 判断
    //       //     olFeature.setId(index)

    //       //     const existArr = featureArr.filter(item => item.id_ === index)
    //       //     if (existArr.length > 0) { // 该网格已存在数组中，重新计算网格测值
    //       //       const exist = existArr[0]
    //       //       const existIndex = featureArr.indexOf(exist)
    //       //       e.valueArr.push(point[data.currentAirIndex] * 1)
    //       //       // 根据当前关注的值进行计算
    //       //       let sum = 0
    //       //       e.valueArr.forEach(value => {
    //       //         sum = sum + value
    //       //       })
    //       //       const averege = sum / e.valueArr.length
    //       //       featureArr[existIndex].aValue = averege
    //       //     } else {
    //       //       olFeature.aValue = point[data.currentAirIndex] * 1
    //       //       e.valueArr.push(point[data.currentAirIndex] * 1)
    //       //       featureArr.push(olFeature)
    //       //     }
    //     }
    //   })
    //   // drawFeature(featureArr)
    // }

    // 获取空气质量指标
    function getAirIndex() {
      getAirDataType().then(res => {
        if (res.code === 0) {
          data.airIndexList = res.data
          data.airIndexList.forEach(e => {
            const option = {
              label: e.name,
              value: e.dataType
            }
            data.selectOption.push(option)
          })
        }
      })
    }
    getAirIndex()

    // // 获取渲染用的方块列表
    // function getSquareList(temp, list) {
    //   const n = data.n
    //   if ((list.length % n) === 0 && list.length > 0) {
    //     data.trackTemp = list.slice(temp * n, (temp + 1) * n)
    //     data.squareList.push(data.trackTemp)
    //     data.trackTemp = []
    //   }
    // }

    // 绘制feature
    function drawFeature(featureArr) {
      if (data.squareLayer) {
        data.map.removeLayer(data.squareLayer)
        data.squareLayer = null
      }
      const featureSource = new VectorSource({
        features: featureArr
      })
      data.featureSource = featureSource
      const layer = new VectorLayer({
        source: featureSource,
        // source: new VectorSource({
        //   features: featureArr
        //   // features:
        // }),
        visible: true,
        zIndex: 1,
        style: function(item) {
          return new Style({
            fill: new Fill({
              color: 'rgba(0,0,0,0)'
            })

          })
        }
      })
      data.map.addLayer(layer)
      data.squareLayer = layer

      // 绘制后添加点击事件
      data.map.on('click', (evt) => {
        squareClick(evt)
      })
    }

    // 方框点击事件
    function squareClick(event) {
      // const feature = data.map.forEachFeatureAtPixel(event.pixel,
      data.map.forEachFeatureAtPixel(event.pixel,
        function(feature, layer) {
          const propsArr = feature.get('propsArr')
          // 对于无数据的直接返回
          if (propsArr.length === 0) return

          const name = '数据点' + feature.get('id')
          // 处理所有需要的数据获得平均值
          // 获取所有的指标
          const indexList = []
          data.airIndexList.forEach(index => {
            indexList.push({ name: index.name, type: index.dataType, unit: 'μg/m³' })
          })
          // 加上高度、湿度、温度、经度、纬度
          // indexList.push({name：'altitude'}, 'humidity', 'temperature', 'longitude', 'latitude')
          indexList.unshift({ name: '高度', type: 'altitude', unit: 'm' }, { name: '经度', type: 'longitude', unit: '°E' }, { name: '纬度', type: 'latitude', unit: '°N' }, { name: '湿度', type: 'humidity', unit: '%rh' })

          // 获取该方块的所有平均值
          const averageProps = []
          indexList.forEach((i, index) => {
            const valueArr = []

            let currentIndex
            if (i.type === 'pm_2_5') {
              currentIndex = 'pm25'
            } else if (i.type === 'pm_10') {
              currentIndex = 'pm10'
            } else {
              currentIndex = i.type
            }

            propsArr.forEach(prop => {
              valueArr.push(prop[currentIndex] * 1)
            })
            // averageProps[i] = getAverage(valueArr)
            averageProps.push({ name: i.name, value: getAverage(valueArr), unit: i.unit, sort: index + 5 })
          })
          // 加上面积属性
          // averageProps.area = data.cellSide * data.cellSide
          averageProps.unshift({ name: '面积', value: data.cellSide * data.cellSide, unit: '㎡', sort: 1 })

          // 弹窗
          const coordinates = feature.get('geometry').flatCoordinates
          createInfowindow({ averageProps, name }, coordinates)
        })
    }
    // 创建弹窗
    function createInfowindow(props, coordinates) {
      if (data.mountNode) {
        airInfowindowClose()
      }
      const app = createVNode(squareWindow, {
        info: props
      })
      data.mountNode = document.createElement('div')
      render(app, data.mountNode)
      document.body.appendChild(data.mountNode)

      data.airInfoOverlay = new Overlay({
        id: 'airInfo_overlay',
        element: document.getElementById('squareInfo'),
        offset: [10, 10]
      })
      data.map.addOverlay(data.airInfoOverlay)
      data.airInfoOverlay.setPosition(coordinates)
      data.airInfoOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1
    }

    function airInfowindowClose() {
      if (!data.mountNode) return
      document.body.removeChild(data.mountNode)
      data.mountNode = null
      if (!data.airInfoOverlay) return
      data.map.removeOverlay(data.airInfoOverlay)
      data.airInfoOverlay = null
    }

    const getMapOptions = computed(() => {
      return {
        id: props.id
      }
    })

    /**
     *  初始化地图
     */
    const initMap = () => {
      // 天地图影像图
      const tdtImgMap = new Tile({
        visible: true,
        source: new XYZ({
          crossOrigin: 'anonymous',
          projection: gcj02Mecator,
          url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=6&x={x}&y={y}&z={z}'
        })
      })
      // var wmsSource = new Tile({
      //   source: new TileWMS({
      //     url: 'https://geoserver.t-aaron.com:4080/geoserver/jiangning/wms',
      //     params: { LAYERS: 'jiangning:town' }
      //   })
      // })

      data.view = new View({
        center: transform([118.773136, 31.828065], 'EPSG:4326', 'EPSG:3857'),
        zoom: 11,
        maxZoom: 17
      })
      data.map = new Map({
        // 地图容器
        target: props.id,
        view: data.view,
        layers: [tdtImgMap],
        controls: control.defaults({
          attribution: false,
          rotate: false,
          zoom: false
        })
      })
      // data.map.addLayer(wmsSource)
      // wmsSource.setOpacity(0.3)
      drawAirport()

      // drawDrone(airport.value.longitude, airport.value.latitude)
    }

    /* 获取直播轨迹数据 */
    const getTrackData = async function(id) {
      const res = await getFlightData(id)
      if (res.data.length === 0) return
      data.monitorInfo.height = res.data[0].latitude || 0
      const trackList = res.data
      data.trackList = trackList
      return Promise.resolve({
        trackList
      })
    }
    // getTrackData(props.currentTask)

    const drawAirport = () => {
      if (!airport.value) return
      const lngLat = [
        parseFloat(airport.value.longitude),
        parseFloat(airport.value.latitude)
      ]
      const feature = new Feature({
        geometry: new Point(fromLonLat(lngLat))
      })
      // 要素设置样式
      feature.setStyle(geomStyles('airport'))
      // 要素设置id
      feature.setId(airport.value.id)
      // 添加矢量图层
      const airLayer = new VectorLayer({
        source: new VectorSource({
          features: [feature]
        }),
        visible: true,
        zIndex: 11
      })
      data.map.addLayer(airLayer)
      data.vectorLayers.push(airLayer)
      data.airportLayer = airLayer
    }

    if (!data.map) {
      // data.trackTimer = setInterval(() => {
      //   getTrackData(taskId.value).then(({ trackList }) => {
      //     // 有数据了再画
      //     if (trackList.length > 1) {
      //       setLiveTrack(formatTradeList(trackList))
      //       clearInterval(data.trackTimer)
      //       data.trackTimer = null
      //     }
      //   })
      // }, 2000)
      if (type.value === 'live') {
        data.trackTimer = setInterval(() => {
          getTrackData(taskId.value).then(({ trackList }) => {
            // 有数据了再画
            if (trackList.length > 1) {
              setLiveTrack(formatTradeList(trackList))
              clearInterval(data.trackTimer)
              data.trackTimer = null
            }
          })
        }, 2000)
      } else {
        airData()
        getTrackData(taskId.value).then(({ trackList }) => {
          data.trackList = trackList
          data.trackInfo = initTrack(formatTradeList(trackList), 'liveTrackLayer', 'route')
        })
      }
    }

    /* 加载实时轨迹 */
    const setLiveTrack = function(hisTrackList) {
      var changeTrack
      data.trackInfo = initTrack(hisTrackList, 'liveTrackLayer', 'route')
      if (data.trackInfo.vectorLayer) {
        data.liveTrackLayer.on('change', changeTrack)
      }

      /* 轨迹改变 */
      changeTrack = (event) => {
        try {
          const vectorContext = getVectorContext(event)
          vectorContext.setIndex(100)
          vectorContext.setStyle(styleList['geoMarker'])
          VectorContext.drawGeometry(data.trackInfo.position)
          vectorContext.drawGeometry(data.trackInfo.route)
          data.map.render()
        } catch {
          console.log(event)
        }
      }

      // 两秒钟获取一次数据
      data.socket = setInterval(() => {
        getTrackData(taskId.value).then((res) => {
          if (!res.trackList || res.trackList.length === 0) {
            console.log('轨迹列表为空，请等待机场准备或联系管理员')
            return
          }
          const len = res.trackList.length
          const obj = res.trackList[len - 1]
          const coordinate = fromLonLat([obj?.lng, obj?.lat])
          // const warningLngLat = turf.point(data.warningLngLat)
          // const uavLngLat = turf.point([parseFloat(obj?.lng), parseFloat(obj?.lat)])
          // const distance = turf.distance(warningLngLat, uavLngLat).toFixed(2)
          // emit('distance', distance)
          if (data.trackInfo) {
            data.trackInfo.route.appendCoordinate(coordinate)
            data.trackInfo.vectorLayer.getSource().changed()
            data.trackInfo.position.setCoordinates(coordinate)
          }
        })
        airData()
      }, 1000)
    }

    // 获取大气监测数据
    function airData() {
      getAirtData(taskId.value).then(res => {
        if (res.data.length === 0) {
          console.log('大气监测数据为空，请联系管理员，任务id为', taskId.value)
          return
        }
        data.airData = res.data
        res.data.forEach(e => {
          squareFilter(e)
        })
        // squareFilter(res.data[33])
      })
    }

    // 计算数字数组的平均值
    function getAverage(arr) {
      let num = 0
      arr.forEach(e => {
        num = num + e
      })
      const average = num / arr.length
      return average
    }

    /* 初始化轨迹 */
    const initTrack = function(coordinate, layer, routeType) {
      let vectorLayer = null
      // 路线
      const route = new LineString(coordinate)
      const routeFeature = new Feature({
        type: routeType,
        geometry: route
      })
      const endMarker = new Feature({
        type: 'icon',
        geometry: new Point(route.getLastCoordinate())
      })
      const position = endMarker.getGeometry().clone()
      if (routeType === 'route') { // 轨迹数据
        const geoMarker = new Feature({
          type: 'geoMarker',
          geometry: position
        })
        geoMarker.setProperties({ type: 'geoMarker' }, false)
        if (data.liveTrackLayer) {
          data.liveTrackLayer.setSource(
            new VectorSource({
              features: [geoMarker, routeFeature]
            })
          )
          vectorLayer = data.liveTrackLayer
        } else {
          vectorLayer = new VectorLayer({
            source: new VectorSource({
              features: [geoMarker, routeFeature]
            }),
            style: function(feature) {
              return styleList[feature.get('type')]
            },
            zIndex: 12
          })
        }
        data[layer] = vectorLayer
        data.map.addLayer(data[layer])
        data.view.fit(route, { padding: [30, 30, 30, 30] })
        if (type.value === 'return') {
          const moveFeature = (event) => {
            /* 计算飞行的百分比 */
            const percent = props.videoInfo.currentTime / props.videoInfo.duration
            const currentCoordinate = route.getCoordinateAt(percent)
            position.setCoordinates(currentCoordinate)
            geoMarker.setGeometry(null)
            const vectorContext = getVectorContext(event)
            vectorContext.setStyle(styleList['geoMarker'])
            vectorContext.drawGeometry(position)
            data.map.render()
          }
          vectorLayer.on('postrender', moveFeature.bind())
        }
        return {
          vectorLayer,
          geoMarker,
          route,
          position
        }
      }
    }

    // /* 处理轨迹列表 */
    const formatTradeList = function(trackList) {
      return trackList.map((item) =>
        fromLonLat([parseFloat(item.lng), parseFloat(item.lat)])
      )
    }
    /**
     *  获取打开overlay中最大的 z-index
     */
    const getMaxZOverlay = () => {
      let maxZIndex = 0
      const overlays = data.map.getOverlays().array_
      if (overlays.length) {
        overlays.forEach((item) => {
          const zIndex = item.getElement().parentElement.style.zIndex
          if (zIndex > maxZIndex) {
            maxZIndex = zIndex
          }
        })
      }
      return maxZIndex
    }

    // 结束直播飞行
    const endLiveFly = () => {
      if (data.socket) {
        clearInterval(data.socket)
        data.socket = null
      }
      data.vectorLayers.forEach((layer) => {
        if (layer) {
          data.map.removeLayer(layer)
        }
      })
      data.vectorLayers.length = 0
    }

    // 计算报告所需的数据
    function getReportData() {
      const featureArr = data.featureArr

      const inspectionId = taskId.value
      const airDataType = data.currentAirIndex
      const gridSize = data.cellSide + 'm ×' + data.cellSide + 'm (' + data.cellSide * data.cellSide + '㎡)'
      const averageGridSize = data.cellSide + 'm ×' + data.cellSide + 'm (' + data.cellSide * data.cellSide + '㎡)'
      // const averageGridSize = data.cellSide * data.cellSide + '㎡'
      const gridArea = data.cellSide * data.cellSide * featureArr.length + '㎡'
      const centerPointLongitudeAndLatitude = data.gridCenter
      let gridConcentrationMax = 0
      let gridConcentrationMix = featureArr[0].get('value')
      let maxCord = ''
      let minCord = ''
      let unit = 'μg/m³'
      featureArr.forEach(feature => {
        const gridValue = feature.get('value')
        // gridConcentrationMax = gridConcentrationMax < gridValue ? gridValue : gridConcentrationMax
        // gridConcentrationMix = gridConcentrationMix > gridValue ? gridValue : gridConcentrationMix

        if (gridConcentrationMax < gridValue) {
          gridConcentrationMax = gridValue
          maxCord = feature.get('longitude') + 'E,' + feature.get('latitude') + 'N'
        }

        if (gridConcentrationMix > gridValue) {
          gridConcentrationMix = gridValue
          minCord = feature.get('longitude') + 'E,' + feature.get('latitude') + 'N'
        }
      })
      if (airDataType === 'co') {
        unit = 'mg/m³'
      } else if (airDataType === 'vocs') {
        unit = 'ppm'
      }
      gridConcentrationMax = gridConcentrationMax + ` ${unit} (${maxCord})`
      gridConcentrationMix = gridConcentrationMix + ` ${unit} (${minCord})`

      const params = {
        inspectionId,
        airDataType,
        gridSize,
        averageGridSize,
        gridArea,
        centerPointLongitudeAndLatitude,
        gridConcentrationMax,
        gridConcentrationMix
      }
      return params
    }
    function setLayerVisible(layer, visible) {
      if (layer) {
        layer.setVisible(visible)
      }
    }
    // 获取图片
    function getReportImg() {
      setLayerVisible(data.trackInfo.vectorLayer, false)
      setLayerVisible(data.airportLayer, false)

      // data.airportLayer.setVisible(false)
      data.map.once('rendercomplete', function() {
        const mapCanvas = document.createElement('canvas')
        const size = data.map.getSize()
        mapCanvas.width = size[0]
        mapCanvas.height = size[1]
        const mapContext = mapCanvas.getContext('2d')
        Array.prototype.forEach.call(
          data.map.getViewport().querySelectorAll('.ol-layer canvas, canvas.ol-layer'),
          function(canvas) {
            if (canvas.width > 0) {
              const opacity =
                canvas.parentNode.style.opacity || canvas.style.opacity
              mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity)
              let matrix
              const transform = canvas.style.transform
              if (transform) {
                // Get the transform parameters from the style's transform matrix
                matrix = transform
                  .match(/^matrix\(([^\(]*)\)$/)[1]
                  .split(',')
                  .map(Number)
              } else {
                matrix = [
                  parseFloat(canvas.style.width) / canvas.width,
                  0,
                  0,
                  parseFloat(canvas.style.height) / canvas.height,
                  0,
                  0
                ]
              }
              // Apply the transform to the export map context
              CanvasRenderingContext2D.prototype.setTransform.apply(
                mapContext,
                matrix
              )
              const backgroundColor = canvas.parentNode.style.backgroundColor
              if (backgroundColor) {
                mapContext.fillStyle = backgroundColor
                mapContext.fillRect(0, 0, canvas.width, canvas.height)
              }
              mapContext.drawImage(canvas, 0, 0)
            }
          }
        )
        mapContext.globalAlpha = 1
        mapContext.setTransform(1, 0, 0, 1, 0, 0)

        // 使用跨域的source图层时，比如本例中的天地图图层，要加上允许跨域的配置项 crossOrigin: 'anonymous'，否则canvas无法使用toDataURL()
        const img = mapCanvas.toDataURL()
        upload(img)
        setLayerVisible(data.trackInfo.vectorLayer, true)
        setLayerVisible(data.airportLayer, true)
      })
      data.map.renderSync()
    }

    const dataURLtoFile = (dataUrl, fileName = 'mark.png') => {
      var arr = dataUrl.split(',')
      var mime = arr[0].match(/:(.*?);/)[1]
      var bstr = atob(arr[1])
      var n = bstr.length
      var u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], fileName, { type: mime })
    }
    // 上传到oss
    function upload(file) {
      getOssAuth().then(res => {
        const client = new OSS({
          timeout: 600000,
          region: 'oss-cn-shanghai',
          secure: true,
          accessKeyId: res.data.accessKeyId,
          accessKeySecret: res.data.accessKeySecret,
          stsToken: res.data.securityToken,
          bucket: 'ta-tech-image'
        })
        // uploadOss(client, file).then(res => {
        //   data.ossUrl = res
        // })
        uploadOss(client, file)
      })
    }

    const uploadOss = (client, files) => {
      const file = files
      // const file = files.file
      return new Promise((resolve, reject) => {
        /* 生成随机文件名称 */
        const randomString = Math.random().toString(36).slice(2)
        const suffix = /\.[^\.]+/.exec('PGBackend')
        const timestamp = new Date().getTime()
        const objectName = `imagedir/${randomString}_${timestamp}${suffix}`
        /* 上传文件至oss */
        client.put(objectName, dataURLtoFile(file))
          .then((res) => {
            resolve(res.url)
            const prams = getReportData()
            prams.ossUrl = res.url
            exportReport(prams).then(
              reportRes => {
                if (reportRes.code === 0) {
                  window.open(reportRes.data) // todo
                }
                // data.trackInfo.vectorLayer.setVisible(true)
                // data.airportLayer.setVisible(true)
              }
            )
          })
          .catch((err) => {
            resolve('error')
            console.log(err)
          })
      })
    }

    onMounted(() => {
      initMap()
    })

    onBeforeUnmount(() => {
      if (data.socket) {
        clearInterval(data.socket)
        data.socket = null
      }
      if (data.trackTimer) {
        clearInterval(data.trackTimer)
        data.trackTimer = null
      }
    })

    return {
      ...toRefs(data),
      getMapOptions,
      endLiveFly,
      initTrack,
      getReportData,
      getReportImg
    }
  }
}
</script>

<style lang="scss" scoped>
* {
  user-select: none;
}

.container {
  width: 100vw;
  height: 100vh;
  position: relative;
  overflow: hidden;
}

.map-container {
  position: absolute;
  top: 0px;
  left: 0px;
  right: 0px;
  bottom: 0px;
}

.indexSelector {
  position: relative;
  width: 200px;
  left: 1200px;
  top: 10px;
  z-index: 100;
}

.legend {
  width: 185px;
  z-index: 100;
  position: relative;
  left: 1260px;
  top: 410px;
}
</style>
